home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 17 / CU Amiga Magazine's Super CD-ROM 17 (1997)(EMAP Images)(GB)[!][issue 1997-12].iso / CUCD / Programming / DiceSource / src / dc1 / exp.c < prev    next >
C/C++ Source or Header  |  1997-09-09  |  7KB  |  337 lines

  1. /*
  2.  *    (c)Copyright 1992-1997 Obvious Implementations Corp.  Redistribution and
  3.  *    use is allowed under the terms of the DICE-LICENSE FILE,
  4.  *    DICE-LICENSE.TXT.
  5.  */
  6.  
  7. /*
  8.  *  EXP.C
  9.  */
  10.  
  11. #include "defs.h"
  12.  
  13. Prototype long ExpToConstant(Exp *);
  14. Prototype Type *ExpToType(Exp *);
  15. Prototype void ExpToLValue(Exp *, Stor *, Type *);
  16. Prototype void InsertCast(Exp **, Type *);
  17. Prototype void InsertNot(Exp **);
  18. Prototype void InsertBranch(Exp **, long, long);
  19. Prototype void InsertAssign(Exp **, Var *);
  20. Prototype long AutoIncDecSize(Exp *);
  21.  
  22. long
  23. ExpToConstant(exp)
  24. Exp *exp;
  25. {
  26.     long value;
  27.     short genPass = GenPass;
  28.  
  29.     Assert(exp);
  30.  
  31.     GenPass = 0;
  32.     (*exp->ex_Func)(&exp);  /*    last arg illegal ptr */
  33.     GenPass = genPass;
  34.  
  35.     if (exp->ex_Stor.st_Type != ST_IntConst) {
  36.     yerror(exp->ex_LexIdx, EERROR_EXPECTED_INT_CONST);
  37.     return(0);
  38.     }
  39.     value = exp->ex_Stor.st_IntConst;
  40.     return(value);
  41. }
  42.  
  43. Type *
  44. ExpToType(exp)
  45. Exp *exp;
  46. {
  47.     short genPass = GenPass;
  48.  
  49.     Assert(exp);
  50.  
  51.     GenPass = 0;
  52.     (*exp->ex_Func)(&exp);  /*    last arg illegal ptr */
  53.     GenPass = genPass;
  54.  
  55.     if (exp->ex_Type == NULL) {
  56.     yerror(exp->ex_LexIdx, EERROR_ILLEGAL_RETURN_TYPE);
  57.     return(&VoidType);
  58.     }
  59.     return(exp->ex_Type);
  60. }
  61.  
  62. /*
  63.  *  Convert an expression to an lvalue whos result type should be
  64.  *  'type'.
  65.  */
  66.  
  67. void
  68. ExpToLValue(exp, stor, type)
  69. Exp *exp;
  70. Stor *stor;
  71. Type *type;
  72. {
  73.     short genPass = GenPass;
  74.  
  75.     Assert(exp);
  76.  
  77. #ifdef NOTDEF
  78.     /*
  79.      *    Propogate const class for string constants
  80.      */
  81.  
  82.     if (exp->ex_Stor.st_Type == ST_StrConst && type->Id == TID_PTR) {
  83.     if (type->SubType->Flags & TF_CONST)
  84.         exp->ex_Flags |= EF_CONST;
  85.     }
  86. #endif
  87.  
  88.     GenPass = 0;
  89.     (*exp->ex_Func)(&exp);
  90.     GenPass = 1;
  91.     (*exp->ex_Func)(&exp);
  92.     GenPass = genPass;
  93.  
  94.     *stor = exp->ex_Stor;
  95.     if (stor->st_Type == ST_IntConst || stor->st_Type == ST_StrConst || stor->st_Type == ST_FltConst) {
  96.     stor->st_Size = type->Size;
  97.     return;
  98.     }
  99.     if (exp->ex_Type->Id == TID_ARY) {
  100.     stor->st_Flags |= SF_LEA;
  101.     return;
  102.     }
  103.  
  104.     if ((stor->st_Flags & SF_LEA) == 0)
  105.     yerror(exp->ex_LexIdx, EERROR_NOT_LVALUE);
  106.     if (stor->st_Type == ST_RelReg || stor->st_Type == ST_RelArg)
  107.     yerror(exp->ex_LexIdx, EERROR_NOT_LVALUE);
  108. }
  109.  
  110. /*
  111.  *  Casting (BEFORE pass 0)
  112.  *
  113.  *  Note that an explicit (cast) does not call this routine, but goes
  114.  *  directly to GenCast.
  115.  */
  116.  
  117. void
  118. InsertCast(pexp, type)
  119. Exp **pexp;
  120. Type *type;
  121. {
  122.     Exp *exp;
  123.     Exp *e1 = *pexp;
  124.     Type *etype = e1->ex_Type;
  125.  
  126.     Assert(etype);
  127.  
  128.     if (etype->Id == TID_BITFIELD)    /*  force the cast  */
  129.     goto force;
  130.  
  131.     /*
  132.      *    Conversions that require no modifications other then unsignedness,
  133.      *    which is handled by other routines (example: GenVarRef checks for
  134.      *    ex_Type changes)
  135.      */
  136.  
  137.     if (type->Size == etype->Size && etype->Id == type->Id && (type->Id == TID_INT || type->Id == TID_FLT)) {
  138.     e1->ex_Type = type;
  139.     return;
  140.     }
  141.  
  142.     /*
  143.      *    Integer  Constant to (Integer | Pointer)
  144.      *    Floating Constant to (Integer | Pointer)
  145.      */
  146.  
  147.  
  148.     if (type->Id == TID_INT || type->Id == TID_PTR) {
  149.     if (e1->ex_Stor.st_Type == ST_IntConst) {
  150.         short sv = type->Size;
  151.  
  152.         if (type->Flags & TF_UNSIGNED)
  153.         sv |= 256;
  154.         switch(sv) {
  155.         case 0:
  156.         e1->ex_Stor.st_IntConst = 0;
  157.         /* XXX */
  158.         break;
  159.         case 1:
  160.         e1->ex_Stor.st_IntConst = (long)(char)e1->ex_Stor.st_IntConst;
  161.         break;
  162.         case 2:
  163.         e1->ex_Stor.st_IntConst = (long)(short)e1->ex_Stor.st_IntConst;
  164.         break;
  165.         case 4:
  166.         break;
  167.         case 256:
  168.         /* XXX */
  169.         e1->ex_Stor.st_IntConst = 0;
  170.         break;
  171.         case 256|1:
  172.         e1->ex_Stor.st_IntConst = (long)(unsigned char)e1->ex_Stor.st_IntConst;
  173.         break;
  174.         case 256|2:
  175.         e1->ex_Stor.st_IntConst = (long)(unsigned short)e1->ex_Stor.st_IntConst;
  176.         break;
  177.         case 256|4:
  178.         break;
  179.         default:
  180.         dbprintf(("InsertCast: bad size const-cast: %ld\n",type->Size));
  181.             Assert(0);
  182.         break;
  183.         }
  184.         e1->ex_Type = type;
  185.         return;
  186.     }
  187.  
  188.     /*
  189.      *  Floating constant to integer
  190.      *
  191.      *  e1->ex_StrConst  e1->ex_StrLen
  192.      */
  193.  
  194.     if (e1->ex_Token == TokFltConst) {
  195.         AllocConstStor(&e1->ex_Stor, FPStrToInt(e1, e1->ex_Stor.st_FltConst, e1->ex_Stor.st_FltLen), type);
  196.         e1->ex_Token = TokIntConst;
  197.         e1->ex_Func = GenIntConst;
  198.         e1->ex_Type = type;
  199.         return;
  200.     }
  201.     }
  202.  
  203.     /*
  204.      *    Floating Constant to Floating    (no chg)
  205.      *    Integer Constant to  Floating    ??
  206.      */
  207.  
  208.     if (type->Id == TID_FLT) {
  209.     if (e1->ex_Stor.st_Type == ST_IntConst) {
  210.         e1->ex_Stor.st_FltConst = IntToFPStr(e1->ex_Stor.st_IntConst, e1->ex_Stor.st_Flags & SF_UNSIGNED, &e1->ex_Stor.st_FltLen);
  211.         e1->ex_Type = type;
  212.         e1->ex_Stor.st_Size = e1->ex_Type->Size;
  213.         e1->ex_Stor.st_Type = ST_FltConst;
  214.         e1->ex_Token = TokFltConst;
  215.         e1->ex_Func  = GenFltConst;
  216.         return;
  217.     }
  218.     if (e1->ex_Token == TokFltConst) {
  219.         e1->ex_Type = type;
  220.         return;
  221.     }
  222.     }
  223.  
  224. force:
  225.     exp = AllocTmpStructure(Exp);
  226.     exp->ex_Next = e1->ex_Next;
  227.     exp->ex_LexIdx = e1->ex_LexIdx;
  228.     exp->ex_Func = GenCast;
  229.     exp->ex_ExpL = e1;
  230.     exp->ex_Type = type;
  231.     exp->ex_Flags= (e1->ex_Flags & EF_CALL) | EF_ICAST;
  232.     exp->ex_Token = TokCast;
  233.  
  234.     *pexp = exp;
  235.     (*exp->ex_Func)(pexp);
  236. }
  237.  
  238. /*
  239.  *  InsertNot() (also used to insert general exp's)
  240.  */
  241.  
  242. void
  243. InsertNot(pexp)
  244. Exp **pexp;
  245. {
  246.     Exp *exp = AllocStructure(Exp);
  247.     Exp *e1 = *pexp;
  248.  
  249.     exp->ex_Func = GenNot;
  250.     exp->ex_ExpL = e1;
  251.     exp->ex_LexIdx = e1->ex_LexIdx;
  252.     exp->ex_Flags = e1->ex_Flags & EF_CALL;
  253.  
  254.     *pexp = exp;
  255. }
  256.  
  257. /*
  258.  *  insert branch on COND_T (1) or COND_F (-1).  See GenBool() for the
  259.  *  specific generation routine.  In many cases conditionals can be 100%
  260.  *  optimized.
  261.  */
  262.  
  263. void
  264. InsertBranch(pexp, cond, label)
  265. Exp **pexp;
  266. long cond;
  267. long label;
  268. {
  269.     Exp *exp;
  270.     Exp *e1 = *pexp;
  271.  
  272.     exp = AllocStructure(Exp);
  273.     exp->ex_Func = GenCondBranch;
  274.     if (cond >= 0)
  275.     exp->ex_LabelT= label;
  276.     else
  277.     exp->ex_LabelF= label;
  278.     exp->ex_Cond = cond;
  279.     exp->ex_ExpL = e1;
  280.     exp->ex_LexIdx = e1->ex_LexIdx;
  281.     exp->ex_Flags= e1->ex_Flags & EF_CALL;
  282.     *pexp = exp;
  283. }
  284.  
  285. /*
  286.  *  Converts exp to var = exp
  287.  */
  288.  
  289. void
  290. InsertAssign(pexp, var)
  291. Exp **pexp;
  292. Var *var;
  293. {
  294.     Exp *exp =    AllocStructure(Exp);
  295.     Exp *evar = AllocStructure(Exp);
  296.     Exp *e1 = *pexp;
  297.  
  298.     Assert(e1);
  299.  
  300.     evar->ex_Func   = GenVarRef;
  301.     evar->ex_Token  = TokVarRef;
  302.     evar->ex_Symbol = var->Sym;
  303.     evar->ex_Var    = var;
  304.     evar->ex_LexIdx = e1->ex_LexIdx;
  305.  
  306.     if (e1->ex_Token == TokExpAssBlock)
  307.     exp->ex_Func = GenBracEq;
  308.     else
  309.     exp->ex_Func = GenEq;
  310.     exp->ex_ExpL = evar;
  311.     exp->ex_ExpR = e1;
  312.     exp->ex_LexIdx= (*pexp)->ex_LexIdx;
  313.     exp->ex_Flags = e1->ex_Flags & EF_CALL;
  314.  
  315.     *pexp = exp;
  316. }
  317.  
  318. /*
  319.  *  Determine amount of increment/decrement.
  320.  */
  321.  
  322. long
  323. AutoIncDecSize(exp)
  324. Exp *exp;
  325. {
  326.     Type *type = exp->ex_Type;
  327.  
  328.     Assert(type);
  329.     if (type->Id == TID_PTR)
  330.     return(type->SubType->Size);
  331.     if (type->Id == TID_INT)
  332.     return(1);
  333.     yerror(exp->ex_LexIdx, EERROR_NOT_LVALUE);
  334.     return(0);
  335. }
  336.  
  337.